/*******************************************************************************
 * FilePath    : /Software/Examples_Ble_MS1658/ble_app_peripheral_uart/Src/BSP/Flash.c
 * Version     : 1.0
 * Brief       : 
 * Author      : AndrewHu
 * Company     : Shanghai MacroGiga Electronics CO.,Ltd
 * Email       : Hubinbo@macrogiga.com
 * Date        : 2020-04-22 11:01:30
 * LastEditors : AndrewHu
 * LastEditTime: 2021-07-05 09:39:08
 * Description : 
 ******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include <Includes.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
//数据存储地址分配
#define FlashBaseAddr ((u32)0x0000e000)
#define BleAddr_len 6
#define FlashAddr_BleAddr FlashBaseAddr
#define BleName_len 28
#define FlashAddr_BleName ((u32)(FlashAddr_BleAddr + BleAddr_len))
#define BleAdvData_len 32
#define FlashAddr_BleAdvData ((u32)(FlashAddr_BleName + BleName_len))
#define BleAdvIn_len 2
#define FlashAddr_BleAdvIn ((u32)(FlashAddr_BleAdvData + BleAdvData_len))
#define UartBaud_len 4
#define FlashAddr_UartBaud ((u32)(FlashAddr_BleAdvIn + BleAdvIn_len))
#define BleMode_len 2
#define FlashAddr_BleMode ((u32)(FlashAddr_UartBaud + UartBaud_len))

#define FlashAddr_Else ((u32)(FlashAddr_BleMode + BleMode_len))
#define BleElse_len ((u32)(1024 - (FlashAddr_Else - FlashBaseAddr)))
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u8 flashFlag = FLASH_WRITE_ENABLE;

//蓝牙地址
const u8 flashBleAddr[BleAddr_len] __attribute__((at(FlashAddr_BleAddr))) = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //mac地址
};
//蓝牙设备名
const u8 flashBleName[BleName_len] __attribute__((at(FlashAddr_BleName))) = {
    11,                                //设备名称长度，最长24个字节
    'M', 'S', '1', '6', '5', '8', '-', //
    'U', 'A', 'R', 'T',                //
};
//蓝牙广播数据
const u8 flashBleAdvData[BleAdvData_len] __attribute__((at(FlashAddr_BleAdvData))) = {
    //定义广播类容,不超过31个字节
    //AD Structure 1
    0x02, //length,except itself
    0x01, //AD Type
    0x04, //AD Data

    //AD Structure 2
    0x1b,                               //length,except itself
    0xff,                               //AD Type
    0x9c, 0x05,                         //Company ID:MacroGiga Electronics<0x059C>
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //Manufacturer specific data
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //

    31, //上定义的广播总长度
};
//广播间隔设定
const u16 flashBleAdvIn __attribute__((at(FlashAddr_BleAdvIn))) = 160 * 2; //默认200毫秒
//串口波特率
const u32 flashUartBaud __attribute__((at(FlashAddr_UartBaud))) = BaudRate_Def; //115200,
//ble工作模式设定
const u16 flashBleMode __attribute__((at(FlashAddr_BleMode))) = 0x0001; //0x00-UART,0x01-ATCMD;00-hex,01-ascii;
//剩余数据
const u8 flashElse[BleElse_len] __attribute__((at(FlashAddr_Else))) = {
    0x00,
};
/* Private function ----------------------------------------------------------*/
/* extern --------------------------------------------------------------------*/
/*******************************************************************************
 * Function    : 
 * Brief       : 
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 14:26:41
 * Description : 
 ******************************************************************************/
void SetFlashFlag(u8 flag)
{
    flashFlag = flag;
}
/*******************************************************************************
 * Function    : readFlash_Mode
 * Brief       : 取出BLE工作模式
 * Parameter   : {u16*} adder-传入地址数据
 * Returns     : 
 * Date        : 2020-04-22 11:33:15
 * Description : 
 ******************************************************************************/
static void readFlash_Mode(u16 *adder)
{
    u32 flashAddr; //起始地址
    flashAddr = FlashAddr_BleMode;
    *adder = (*(__IO u16 *)flashAddr);
}
/*******************************************************************************
 * Function    : readFlash_bleAddr
 * Brief       : 取出MAC地址
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 11:35:08
 * Description : 
 ******************************************************************************/
static void readFlash_bleAddr(u8 *adder)
{
    u32 flashAddr; //起始地址
    u8 i = 0x00;
    flashAddr = FlashAddr_BleAddr;
    for (i = 0; i < BleAddr_len; i++)
    {
        adder[i] = (*(__IO u8 *)flashAddr);
        flashAddr++;
    }
}
/*******************************************************************************
 * Function    : readFlash_bleName
 * Brief       : 读取设备名
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 11:35:24
 * Description : 
 ******************************************************************************/
static void readFlash_bleName(u8 *adder)
{
    u32 flashAddr; //起始地址
    u8 i = 0x00;
    flashAddr = FlashAddr_BleName;
    for (i = 0; i < (BleName_len - 1); i++) //不超过25个字节
    {
        adder[i] = (*(__IO u8 *)flashAddr);
        flashAddr++;
    }
}
/*******************************************************************************
 * Function    : readFlash_bleAdvData
 * Brief       : 读取广播数据
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 14:08:40
 * Description : 
 ******************************************************************************/
static void readFlash_bleAdvData(u8 *adder)
{
    u32 flashAddr; //起始地址
    u8 i = 0x00;
    flashAddr = FlashAddr_BleAdvData;
    for (i = 0; i < (BleAdvData_len); i++) //不超过25个字节
    {
        adder[i] = (*(__IO u8 *)flashAddr);
        flashAddr++;
    }
}
/*******************************************************************************
 * Function    : readFlash_bleAdvIn
 * Brief       : 读取广播间隔
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 11:38:15
 * Description : 
 ******************************************************************************/
static void readFlash_bleAdvIn(u16 *addr)
{
    u32 flashAddr; //起始地址
    flashAddr = FlashAddr_BleAdvIn;
    flashAddr = (*(__IO u16 *)flashAddr);
    *addr = (u16)flashAddr;
}
/*******************************************************************************
 * Function    : readFlash_uartBaud
 * Brief       : 读取串口波特率
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 11:37:49
 * Description : 
 ******************************************************************************/
static void readFlash_uartBaud(u32 *addr)
{
    u32 flashAddr; //起始地址
    flashAddr = FlashAddr_UartBaud;
    *addr = (*(__IO u32 *)flashAddr);
}
/*******************************************************************************
 * Function    : Flash_Run
 * Brief       : Flash数据操作
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 11:38:52
 * Description : (flashFlag != 0)时，数据要更新
 *               写入前会按页擦除，所有数据都要重新写入一次
 ******************************************************************************/
void Flash_Run(void)
{
    u8 i;
    u16 flashtemp_16;
    u32 flashAddr; //起始地址
    u8 len;
    u8 *addr;
    FLASH_EraseInitTypeDef FLASH_EraseInitStruact = {0};
    u32 error;
    FLASH_EraseInitStruact.TypeErase = FLASH_TYPEERASE_PAGES;
    FLASH_EraseInitStruact.PageAddress = FlashBaseAddr;
    FLASH_EraseInitStruact.NbPages = 1;

    if (flashFlag != FLASH_WRITE_ENABLE)
        return; //数据不用更新
    flashFlag = 0x00;

    HAL_FLASH_Erase(&FLASH_EraseInitStruact, &error); //擦除一页

    //写入蓝牙地址
    flashAddr = FlashAddr_BleAddr;
    addr = getBleAddr();
    for (i = 0; i < BleAddr_len; i += 2)
    {
        flashtemp_16 = addr[i + 1];
        flashtemp_16 <<= 8;
        flashtemp_16 |= addr[i];
        HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, flashAddr, flashtemp_16);
        flashAddr += 2;
    }

    //写入设备名
    addr = getDeviceInfoData(&len);
    if (len <= 24)
    {
        addr--;
        len++;

        flashAddr = FlashAddr_BleName;
        for (i = 0; i < len; i += 2)
        {
            flashtemp_16 = addr[i + 1];
            flashtemp_16 <<= 8;
            flashtemp_16 |= addr[i];
            HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, flashAddr, flashtemp_16);
            flashAddr += 0x02;
        }
    }

    //写入蓝牙广播数据
    addr = GetAdvData();
    if (len <= 31)
    {
        flashAddr = FlashAddr_BleAdvData;
        for (i = 0; i < BleAdvData_len; i += 2)
        {
            flashtemp_16 = addr[i + 1];
            flashtemp_16 <<= 8;
            flashtemp_16 |= addr[i];
            HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, flashAddr, flashtemp_16);
            flashAddr += 0x02;
        }
    }

    //写入广播间隔
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddr_BleAdvIn, GetBleAdvInterval());

    //写入波特率
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, FlashAddr_UartBaud, GetBaudRate());

    //写入工作模式、通讯格式
    flashtemp_16 = getBleMode();
    flashtemp_16 = (flashtemp_16 << 8) + GetDataType();
    HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FlashAddr_BleMode, flashtemp_16);

    //test
    //    readFlash_bleName(temp);
    //    Uart_Send_String(temp + 1, temp[0]);
}
/*******************************************************************************
 * Function    : Flash_Read
 * Brief       : 读取数据
 * Parameter   : 
 * Returns     : 
 * Date        : 2020-04-22 12:30:21
 * Description : 
 ******************************************************************************/
void Flash_Read(void)
{
    u8 ble_temp[50];
    u16 ble_temp16 = 0;
    u32 ble_temp32 = 0;

    //Mac地址判断/更新
    readFlash_bleAddr(getBleAddr()); //从flash中读取地址

    //Device Name
    readFlash_bleName(ble_temp);
    if ((ble_temp[0] != 0x00) && (ble_temp[0] <= 24))
    {
        updateDeviceInfoData((u8 *)(ble_temp + 1), ble_temp[0]);
    }

    //设定广播内容
    readFlash_bleAdvData(ble_temp);
    if (ble_temp[31] == 0x00)
    {
        //没有数据，写入默认数据
        ble_temp[0] = 0x02;
        ble_temp[1] = 0x01;
        ble_temp[2] = 0x04;
        SetAdvData(ble_temp, 3);
    }
    else
    {
        SetAdvData(ble_temp, ble_temp[31]);
    }

    //设定广播间隔
    readFlash_bleAdvIn(&ble_temp16);
    if (ble_temp16 == 0x00)
        SetBleAdvInterval(160 * 2);
    else
        SetBleAdvInterval(ble_temp16);

    //波特率(串口初始化时已更改)
    readFlash_uartBaud(&ble_temp32);
    if ((ble_temp32 == 0x00) || (ble_temp32 == 0xffff))
        ble_temp32 = 115200;
    ChangeBaudRate(ble_temp32);

    //读取工作模式和通讯格式
    readFlash_Mode(&ble_temp16);
    SetDataType(ble_temp16 & 0x00ff);
    setBleMode((u8)(ble_temp16 >> 8));
}
